package com.kurt.service.impl;

import com.kurt.service.BaseService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

import java.util.List;
import java.util.Optional;

/**
 * 基础服务实现类
 * 提供通用的CRUD操作实现
 *
 * @param <T>  实体类型
 * @param <ID> 主键类型
 */
public abstract class BaseServiceImpl<T, ID> implements BaseService<T, ID> {

    /**
     * 获取Repository实例
     * 子类需要实现此方法返回具体的Repository
     *
     * @return Repository实例
     */
    protected abstract JpaRepository<T, ID> getRepository();

    /**
     * 获取SpecificationExecutor实例
     * 子类需要实现此方法返回具体的SpecificationExecutor
     *
     * @return SpecificationExecutor实例
     */
    protected abstract JpaSpecificationExecutor<T> getSpecificationExecutor();

    @Override
    public T save(T entity) {
        return getRepository().save(entity);
    }

    @Override
    public List<T> saveAll(List<T> entities) {
        return getRepository().saveAll(entities);
    }

    @Override
    public Optional<T> findById(ID id) {
        return getRepository().findById(id);
    }

    @Override
    public T getById(ID id) {
        return findById(id).orElseThrow(() -> new RuntimeException("实体不存在，ID: " + id));
    }

    @Override
    public List<T> findAll() {
        return getRepository().findAll();
    }

    @Override
    public List<T> findAllById(List<ID> ids) {
        return getRepository().findAllById(ids);
    }

    @Override
    public Page<T> findAll(Pageable pageable) {
        return getRepository().findAll(pageable);
    }

    @Override
    public Page<T> findAll(Specification<T> spec, Pageable pageable) {
        return getSpecificationExecutor().findAll(spec, pageable);
    }

    @Override
    public List<T> findAll(Specification<T> spec) {
        return getSpecificationExecutor().findAll(spec);
    }

    @Override
    public boolean deleteById(ID id) {
        getRepository().deleteById(id);
        return false;
    }

    @Override
    public void delete(T entity) {
        getRepository().delete(entity);
    }

    @Override
    public void deleteAll(List<T> entities) {
        getRepository().deleteAll(entities);
    }

    @Override
    public void deleteAllById(List<ID> ids) {
        getRepository().deleteAllById(ids);
    }

    @Override
    public boolean existsById(ID id) {
        return getRepository().existsById(id);
    }

    @Override
    public long count() {
        return getRepository().count();
    }

    @Override
    public long count(Specification<T> spec) {
        return getSpecificationExecutor().count(spec);
    }
}
